/**
 * 多模型服务
 * 整合多模型功能，提供统一的调用接口
 */

import { BaseModelAdapter, ModelType, ModelConfig, ModelResponse, StreamResponse } from './models/base-model-adapter';
import { ModelRouter, ModelSelectionCriteria } from './models/model-router';
import { OpenAIAdapter } from './models/openai-adapter';
import { ClaudeAdapter } from './models/claude-adapter';

export interface MultiModelConfig {
  openai?: {
    apiKey: string;
    baseUrl?: string;
  };
  claude?: {
    apiKey: string;
    baseUrl?: string;
  };
  wenxin?: {
    apiKey: string;
    secretKey: string;
  };
  qwen?: {
    apiKey: string;
  };
}

export interface ComparisonResult {
  modelType: ModelType;
  response: ModelResponse;
  duration: number;
  error?: string;
}

export interface ComparisonRequest {
  prompt: string;
  models: ModelType[];
  criteria?: ModelSelectionCriteria;
  maxConcurrency?: number;
}

export class MultiModelService {
  private router: ModelRouter;
  private config: MultiModelConfig;

  constructor(config: MultiModelConfig) {
    this.config = config;
    this.router = new ModelRouter();
    this.initializeAdapters();
  }

  /**
   * 初始化模型适配器
   */
  private initializeAdapters() {
    const defaultConfig: ModelConfig = {
      apiKey: '',
      maxTokens: 4096,
      temperature: 0.7,
      timeout: 30000,
      retryAttempts: 3
    };

    // 初始化OpenAI适配器
    if (this.config.openai?.apiKey) {
      const gpt4Adapter = new OpenAIAdapter(
        { ...defaultConfig, apiKey: this.config.openai.apiKey, baseUrl: this.config.openai.baseUrl },
        ModelType.GPT4
      );
      const gpt35Adapter = new OpenAIAdapter(
        { ...defaultConfig, apiKey: this.config.openai.apiKey, baseUrl: this.config.openai.baseUrl },
        ModelType.GPT35
      );
      
      this.router.registerAdapter(ModelType.GPT4, gpt4Adapter);
      this.router.registerAdapter(ModelType.GPT35, gpt35Adapter);
    }

    // 初始化Claude适配器
    if (this.config.claude?.apiKey) {
      const claudeAdapter = new ClaudeAdapter(
        { ...defaultConfig, apiKey: this.config.claude.apiKey, baseUrl: this.config.claude.baseUrl },
        ModelType.CLAUDE
      );
      
      this.router.registerAdapter(ModelType.CLAUDE, claudeAdapter);
    }

    // TODO: 添加其他模型适配器的初始化
  }

  /**
   * 智能生成内容
   * 自动选择最佳模型
   */
  async generateContent(
    prompt: string, 
    criteria?: ModelSelectionCriteria,
    options?: Partial<ModelConfig>
  ): Promise<ModelResponse> {
    const selectedModel = this.router.selectModel(criteria);
    
    if (!selectedModel) {
      throw new Error('No healthy models available');
    }

    const adapter = this.router.getAdapter(selectedModel);
    if (!adapter) {
      throw new Error(`Adapter not found for model: ${selectedModel}`);
    }

    try {
      return await adapter.generate(prompt, options);
    } catch (error) {
      console.error(`Generation failed with ${selectedModel}:`, error);
      
      // 尝试故障转移
      const fallbackModel = this.router.getFallbackModel(selectedModel, criteria?.taskType);
      if (fallbackModel) {
        const fallbackAdapter = this.router.getAdapter(fallbackModel);
        if (fallbackAdapter) {
          console.log(`Falling back to ${fallbackModel}`);
          return await fallbackAdapter.generate(prompt, options);
        }
      }
      
      throw error;
    }
  }

  /**
   * 流式生成内容
   */
  async streamContent(
    prompt: string,
    onChunk: (chunk: StreamResponse) => void,
    criteria?: ModelSelectionCriteria,
    options?: Partial<ModelConfig>
  ): Promise<void> {
    const selectedModel = this.router.selectModel(criteria);
    
    if (!selectedModel) {
      throw new Error('No healthy models available');
    }

    const adapter = this.router.getAdapter(selectedModel);
    if (!adapter) {
      throw new Error(`Adapter not found for model: ${selectedModel}`);
    }

    try {
      await adapter.stream(prompt, onChunk, options);
    } catch (error) {
      console.error(`Streaming failed with ${selectedModel}:`, error);
      
      // 尝试故障转移
      const fallbackModel = this.router.getFallbackModel(selectedModel, criteria?.taskType);
      if (fallbackModel) {
        const fallbackAdapter = this.router.getAdapter(fallbackModel);
        if (fallbackAdapter) {
          console.log(`Falling back to ${fallbackModel}`);
          await fallbackAdapter.stream(prompt, onChunk, options);
          return;
        }
      }
      
      throw error;
    }
  }

  /**
   * 多模型对比生成
   * 并行调用多个模型进行对比
   */
  async compareModels(request: ComparisonRequest): Promise<ComparisonResult[]> {
    const { prompt, models, maxConcurrency = 3 } = request;
    const results: ComparisonResult[] = [];

    // 分批处理，避免过多并发请求
    for (let i = 0; i < models.length; i += maxConcurrency) {
      const batch = models.slice(i, i + maxConcurrency);
      const batchPromises = batch.map(async (modelType) => {
        const startTime = Date.now();
        
        try {
          const adapter = this.router.getAdapter(modelType);
          if (!adapter) {
            return {
              modelType,
              response: {} as ModelResponse,
              duration: 0,
              error: `Adapter not found for ${modelType}`
            };
          }

          const response = await adapter.generate(prompt);
          const duration = Date.now() - startTime;

          return {
            modelType,
            response,
            duration,
          };
        } catch (error) {
          const duration = Date.now() - startTime;
          return {
            modelType,
            response: {} as ModelResponse,
            duration,
            error: error instanceof Error ? error.message : 'Unknown error'
          };
        }
      });

      const batchResults = await Promise.all(batchPromises);
      results.push(...batchResults);
    }

    return results;
  }

  /**
   * 获取可用模型列表
   */
  getAvailableModels(): ModelType[] {
    return this.router.getHealthStatus()
      .filter(health => health.isHealthy)
      .map(health => health.modelType);
  }

  /**
   * 获取模型健康状态
   */
  getModelHealth() {
    return this.router.getHealthStatus();
  }

  /**
   * 获取模型统计信息
   */
  getModelStats() {
    return this.router.getModelStats();
  }

  /**
   * 估算生成成本
   */
  async estimateGenerationCost(prompt: string, modelType?: ModelType): Promise<number> {
    const targetModel = modelType || this.router.selectModel();
    
    if (!targetModel) {
      return 0;
    }

    const adapter = this.router.getAdapter(targetModel);
    if (!adapter) {
      return 0;
    }

    const promptTokens = await adapter.countTokens(prompt);
    const estimatedCompletionTokens = Math.min(promptTokens * 0.5, 1000); // 估算回复长度
    
    return adapter.estimateCost(promptTokens, estimatedCompletionTokens);
  }

  /**
   * 批量生成内容
   */
  async batchGenerate(
    prompts: string[],
    criteria?: ModelSelectionCriteria,
    options?: Partial<ModelConfig>
  ): Promise<ModelResponse[]> {
    const results: ModelResponse[] = [];
    
    // 并行处理，但限制并发数
    const maxConcurrency = 5;
    for (let i = 0; i < prompts.length; i += maxConcurrency) {
      const batch = prompts.slice(i, i + maxConcurrency);
      const batchPromises = batch.map(prompt => 
        this.generateContent(prompt, criteria, options)
      );
      
      const batchResults = await Promise.all(batchPromises);
      results.push(...batchResults);
    }

    return results;
  }
}
